using System;
using System.IO;
using System.Threading.Tasks;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Linq;

namespace AvaAI批量点评系统.Services;

/// <summary>
/// 摄像头服务 - 提供真正的摄像头拍照功能
/// </summary>
public class CameraService
{
    private const string TEMP_FOLDER = "AvaAI_Camera";

    /// <summary>
    /// 拍照并返回图片路径
    /// </summary>
    /// <returns>图片文件路径，如果拍照失败或取消则返回null</returns>
    public async Task<string?> CapturePhotoAsync()
    {
        try
        {
            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                return await CapturePhotoWindowsAsync();
            }
            else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
            {
                return await CapturePhotoMacAsync();
            }
            else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
            {
                return await CapturePhotoLinuxAsync();
            }
            else
            {
                throw new PlatformNotSupportedException("当前平台不支持摄像头功能");
            }
        }
        catch (Exception ex)
        {
            throw new Exception($"摄像头拍照失败: {ex.Message}", ex);
        }
    }

    /// <summary>
    /// Windows平台摄像头拍照
    /// </summary>
    private async Task<string?> CapturePhotoWindowsAsync()
    {
        var tempDir = Path.Combine(Path.GetTempPath(), TEMP_FOLDER);
        Directory.CreateDirectory(tempDir);
        
        var outputPath = Path.Combine(tempDir, $"capture_{DateTime.Now:yyyyMMdd_HHmmss}.jpg");

        // 使用PowerShell和Windows.Media.Capture API进行拍照
        var powershellScript = $@"
Add-Type -AssemblyName System.Runtime.WindowsRuntime
Add-Type -AssemblyName System.Drawing

# 引入Windows Runtime类型
[Windows.ApplicationModel.Core.CoreApplication,Windows.ApplicationModel.Core,ContentType=WindowsRuntime] | Out-Null
[Windows.Media.Capture.MediaCapture,Windows.Media.Capture,ContentType=WindowsRuntime] | Out-Null
[Windows.Storage.StorageFile,Windows.Storage,ContentType=WindowsRuntime] | Out-Null
[Windows.Storage.ApplicationData,Windows.Storage,ContentType=WindowsRuntime] | Out-Null

try {{
    # 创建MediaCapture实例
    $mediaCapture = New-Object Windows.Media.Capture.MediaCapture
    
    # 初始化摄像头
    $initTask = $mediaCapture.InitializeAsync()
    while (-not $initTask.IsCompleted) {{
        Start-Sleep -Milliseconds 100
    }}
    
    if ($initTask.Exception) {{
        throw $initTask.Exception
    }}

    # 创建临时文件
    $tempFile = [Windows.Storage.ApplicationData]::Current.TemporaryFolder.CreateFileAsync(""temp_capture.jpg"", [Windows.Storage.CreationCollisionOption]::ReplaceExisting)
    while (-not $tempFile.IsCompleted) {{
        Start-Sleep -Milliseconds 100
    }}
    
    $file = $tempFile.Result

    # 拍照
    $captureTask = $mediaCapture.CapturePhotoToStorageFileAsync([Windows.Media.Capture.ImageEncodingProperties]::CreateJpeg(), $file)
    while (-not $captureTask.IsCompleted) {{
        Start-Sleep -Milliseconds 100
    }}

    if ($captureTask.Exception) {{
        throw $captureTask.Exception
    }}

    # 复制到目标位置
    Copy-Item $file.Path ""{outputPath}""
    
    # 清理资源
    $mediaCapture.Dispose()
    
    Write-Output ""{outputPath}""
}} catch {{
    Write-Error ""PowerShell摄像头调用失败: $($_.Exception.Message)""
    exit 1
}}
";

        try
        {
            var process = new Process
            {
                StartInfo = new ProcessStartInfo
                {
                    FileName = "powershell.exe",
                    Arguments = $"-ExecutionPolicy Bypass -Command \"{powershellScript}\"",
                    UseShellExecute = false,
                    RedirectStandardOutput = true,
                    RedirectStandardError = true,
                    CreateNoWindow = true
                }
            };

            process.Start();
            var output = await process.StandardOutput.ReadToEndAsync();
            var error = await process.StandardError.ReadToEndAsync();
            await process.WaitForExitAsync();

            if (process.ExitCode == 0 && File.Exists(outputPath))
            {
                return outputPath;
            }
            else
            {
                // 如果PowerShell方法失败，使用Windows摄像头应用的快捷方式
                return await CapturePhotoWithWindowsCameraAppAsync();
            }
        }
        catch
        {
            // 回退到Windows摄像头应用方法
            return await CapturePhotoWithWindowsCameraAppAsync();
        }
    }

    /// <summary>
    /// 使用Windows摄像头应用进行拍照
    /// </summary>
    private async Task<string?> CapturePhotoWithWindowsCameraAppAsync()
    {
        try
        {
            var tempDir = Path.Combine(Path.GetTempPath(), TEMP_FOLDER);
            Directory.CreateDirectory(tempDir);

            // 监控用户图片文件夹的变化
            var picturesPath = Environment.GetFolderPath(Environment.SpecialFolder.MyPictures);
            var cameraRollPath = Path.Combine(picturesPath, "Camera Roll");
            
            if (!Directory.Exists(cameraRollPath))
            {
                cameraRollPath = picturesPath;
            }

            // 获取拍照前的文件列表
            var beforeFiles = Directory.GetFiles(cameraRollPath, "*.jpg")
                .Concat(Directory.GetFiles(cameraRollPath, "*.jpeg"))
                .Concat(Directory.GetFiles(cameraRollPath, "*.png"))
                .OrderByDescending(f => File.GetCreationTime(f))
                .ToArray();

            // 启动Windows摄像头应用
            var process = Process.Start(new ProcessStartInfo
            {
                FileName = "microsoft.windows.camera:",
                UseShellExecute = true
            });

            if (process != null)
            {
                // 等待用户拍照
                await Task.Delay(1000); // 等待应用启动

                // 监控新文件的出现
                for (int i = 0; i < 60; i++) // 等待最多60秒
                {
                    await Task.Delay(1000);

                    var afterFiles = Directory.GetFiles(cameraRollPath, "*.jpg")
                        .Concat(Directory.GetFiles(cameraRollPath, "*.jpeg"))
                        .Concat(Directory.GetFiles(cameraRollPath, "*.png"))
                        .OrderByDescending(f => File.GetCreationTime(f))
                        .ToArray();

                    // 查找新增的文件
                    var newFiles = afterFiles.Except(beforeFiles).ToArray();
                    if (newFiles.Length > 0)
                    {
                        var newestFile = newFiles.OrderByDescending(f => File.GetCreationTime(f)).First();
                        
                        // 检查文件是否在最近30秒内创建
                        if (File.GetCreationTime(newestFile) > DateTime.Now.AddSeconds(-30))
                        {
                            // 复制到临时目录
                            var tempFile = Path.Combine(tempDir, $"capture_{DateTime.Now:yyyyMMdd_HHmmss}{Path.GetExtension(newestFile)}");
                            File.Copy(newestFile, tempFile, true);
                            return tempFile;
                        }
                    }
                }
            }

            return null;
        }
        catch (Exception ex)
        {
            throw new Exception($"Windows摄像头应用拍照失败: {ex.Message}", ex);
        }
    }

    /// <summary>
    /// macOS平台摄像头拍照
    /// </summary>
    private async Task<string?> CapturePhotoMacAsync()
    {
        var tempDir = Path.Combine(Path.GetTempPath(), TEMP_FOLDER);
        Directory.CreateDirectory(tempDir);
        
        var outputPath = Path.Combine(tempDir, $"capture_{DateTime.Now:yyyyMMdd_HHmmss}.jpg");

        var script = $@"
osascript -e 'tell application ""Photo Booth""
    activate
    delay 2
    take picture
    delay 3
    quit
end tell'

# 查找最新的照片
latest_photo=$(ls -t ~/Pictures/ | grep -E '\.(jpg|jpeg|png)$' | head -1)
if [ ! -z ""$latest_photo"" ]; then
    cp ""~/Pictures/$latest_photo"" ""{outputPath}""
    echo ""{outputPath}""
else
    exit 1
fi
";

        try
        {
            var process = new Process
            {
                StartInfo = new ProcessStartInfo
                {
                    FileName = "/bin/bash",
                    Arguments = $"-c \"{script}\"",
                    UseShellExecute = false,
                    RedirectStandardOutput = true,
                    RedirectStandardError = true,
                    CreateNoWindow = true
                }
            };

            process.Start();
            var output = await process.StandardOutput.ReadToEndAsync();
            await process.WaitForExitAsync();

            return process.ExitCode == 0 && File.Exists(outputPath) ? outputPath : null;
        }
        catch (Exception ex)
        {
            throw new Exception($"macOS摄像头拍照失败: {ex.Message}", ex);
        }
    }

    /// <summary>
    /// Linux平台摄像头拍照
    /// </summary>
    private async Task<string?> CapturePhotoLinuxAsync()
    {
        var tempDir = Path.Combine(Path.GetTempPath(), TEMP_FOLDER);
        Directory.CreateDirectory(tempDir);
        
        var outputPath = Path.Combine(tempDir, $"capture_{DateTime.Now:yyyyMMdd_HHmmss}.jpg");

        // 尝试使用fswebcam或其他Linux摄像头工具
        var commands = new[]
        {
            $"fswebcam -r 1280x720 --jpeg 95 -D 1 {outputPath}",
            $"ffmpeg -f v4l2 -i /dev/video0 -vframes 1 {outputPath}",
            $"streamer -c /dev/video0 -b 16 -o {outputPath}"
        };

        foreach (var command in commands)
        {
            try
            {
                var parts = command.Split(' ', 2);
                var process = new Process
                {
                    StartInfo = new ProcessStartInfo
                    {
                        FileName = parts[0],
                        Arguments = parts.Length > 1 ? parts[1] : "",
                        UseShellExecute = false,
                        RedirectStandardOutput = true,
                        RedirectStandardError = true,
                        CreateNoWindow = true
                    }
                };

                process.Start();
                await process.WaitForExitAsync();

                if (process.ExitCode == 0 && File.Exists(outputPath))
                {
                    return outputPath;
                }
            }
            catch
            {
                // 尝试下一个命令
                continue;
            }
        }

        throw new Exception("Linux平台未找到可用的摄像头工具，请安装fswebcam、ffmpeg或streamer");
    }

    /// <summary>
    /// 检查摄像头是否可用
    /// </summary>
    public async Task<bool> IsCameraAvailableAsync()
    {
        try
        {
            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                return await CheckWindowsCameraAsync();
            }
            else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
            {
                return await CheckMacCameraAsync();
            }
            else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
            {
                return await CheckLinuxCameraAsync();
            }
            return false;
        }
        catch
        {
            return false;
        }
    }

    private async Task<bool> CheckWindowsCameraAsync()
    {
        try
        {
            var script = @"
Get-PnpDevice -Class Camera | Where-Object {$_.Status -eq 'OK'} | Measure-Object | Select-Object -ExpandProperty Count
";
            var process = new Process
            {
                StartInfo = new ProcessStartInfo
                {
                    FileName = "powershell.exe",
                    Arguments = $"-Command \"{script}\"",
                    UseShellExecute = false,
                    RedirectStandardOutput = true,
                    CreateNoWindow = true
                }
            };

            process.Start();
            var output = await process.StandardOutput.ReadToEndAsync();
            await process.WaitForExitAsync();

            return int.TryParse(output.Trim(), out var count) && count > 0;
        }
        catch
        {
            return false;
        }
    }

    private async Task<bool> CheckMacCameraAsync()
    {
        try
        {
            var process = new Process
            {
                StartInfo = new ProcessStartInfo
                {
                    FileName = "/usr/sbin/system_profiler",
                    Arguments = "SPCameraDataType",
                    UseShellExecute = false,
                    RedirectStandardOutput = true,
                    CreateNoWindow = true
                }
            };

            process.Start();
            var output = await process.StandardOutput.ReadToEndAsync();
            await process.WaitForExitAsync();

            return output.Contains("Camera") && !output.Contains("No items found");
        }
        catch
        {
            return false;
        }
    }

    private async Task<bool> CheckLinuxCameraAsync()
    {
        try
        {
            var process = new Process
            {
                StartInfo = new ProcessStartInfo
                {
                    FileName = "/bin/ls",
                    Arguments = "/dev/video*",
                    UseShellExecute = false,
                    RedirectStandardOutput = true,
                    RedirectStandardError = true,
                    CreateNoWindow = true
                }
            };

            process.Start();
            await process.WaitForExitAsync();

            return process.ExitCode == 0;
        }
        catch
        {
            return false;
        }
    }

    /// <summary>
    /// 清理临时文件
    /// </summary>
    public void CleanupTempFiles()
    {
        try
        {
            var tempDir = Path.Combine(Path.GetTempPath(), TEMP_FOLDER);
            if (Directory.Exists(tempDir))
            {
                var files = Directory.GetFiles(tempDir);
                foreach (var file in files)
                {
                    try
                    {
                        // 删除30分钟前的文件
                        if (File.GetCreationTime(file) < DateTime.Now.AddMinutes(-30))
                        {
                            File.Delete(file);
                        }
                    }
                    catch
                    {
                        // 忽略单个文件删除失败
                    }
                }
            }
        }
        catch
        {
            // 忽略清理失败
        }
    }
}